/**
 * @file SimpleCDNET.h
 * @brief CDNET协议栈Arduino封装类
 * @details
 * 提供CDNET协议栈的完整Arduino封装，支持Layer 0和Layer 1操作，
 * 集成CDNET核心功能，包括套接字管理、路由、多网络支持等。
 * 
 * 功能特性：
 * - Layer 0（节点内通信）和Layer 1（网络间通信）
 * - CDNET核心协议栈集成
 * - 套接字管理和绑定
 * - 多网络和多播支持
 * - 数据包池管理
 * - 自动路由和转发
 * 
 * 硬件支持：
 * - Arduino UNO/Nano（使用SoftwareSerial）
 * - Arduino Mega（硬件Serial1/2/3）
 * - STM32系列（硬件Serial）
 * - ESP32/ESP8266（硬件Serial）
 * 
 * @author CDBUS开发团队
 * @copyright MIT License
 * @date 2024
 * 
 * @note 需要配合SimpleCDBUS库使用
 * @warning 确保正确配置网络ID和MAC地址以避免冲突
 * 
 * 使用示例：
 * @code
 * #include <SimpleCDNET.h>
 * 
 * SimpleCDNET cdnet;
 * 
 * void setup() {
 *   Serial.begin(115200);
 *   cdnet.begin(&Serial1, 0x01, 0x10); // 网络ID=1, MAC地址=0x10
 *   cdnet.setBaudRate(1000000);       // 设置波特率
 * }
 * 
 * void loop() {
 *   cdnet.update(); // 定期更新协议栈
 *   
 *   if (cdnet.available()) {
 *     uint8_t src, port;
 *     uint8_t buffer[64];
 *     uint8_t len = cdnet.readL0(&src, &port, buffer, sizeof(buffer));
 *     if (len > 0) {
 *       // 处理接收到的数据
 *     }
 *   }
 * }
 * @endcode
 */

#ifndef SIMPLE_CDNET_H
#define SIMPLE_CDNET_H

#include <Arduino.h>
#include "SimpleCDBUS.h"
#include "cdnet.h"
#include "cdnet_core.h"

/**
 * @class SimpleCDNET
 * @brief CDNET协议栈Arduino封装类
 * 
 * 提供完整的CDNET协议栈功能，包括：
 * - 基础Layer 0/1通信
 * - 高级套接字管理
 * - 网络路由和转发
 * - 多网络和多播支持
 * - 数据包池管理
 */
class SimpleCDNET {
private:
    /** @brief 底层CDBUS总线接口 */
    SimpleCDBUS _cdbus;
    
    /** @brief CDNET接收缓冲区 */
    uint8_t _rx_buffer[CDNET_MAX_PACKET_SIZE];
    /** @brief CDNET发送缓冲区 */
    uint8_t _tx_buffer[CDNET_MAX_PACKET_SIZE];
    
    /** @brief CDNET协议状态 */
    cdnet_t _cdnet;
    
    /** @brief CDNET核心命名空间 */
    cdn_ns_t _cdnet_ns;
    /** @brief 空闲数据包链表头 */
    list_head_t _free_pkt;
    /** @brief 空闲帧链表头 */
    list_head_t _free_frm;
    /** @brief 数据包池（8个预分配数据包） */
    cdn_pkt_t _pkt_pool[8];
    /** @brief 帧池（8个预分配帧） */
    cd_frame_t _frame_pool[8];
    
    /** @brief 网络标识符（用于多网络区分） */
    uint8_t _net_id;
    /** @brief MAC地址（本地设备地址） */
    uint8_t _mac_address;
    /** @brief 多播功能开关 */
    bool _multicast_enabled;
    /** @brief 多网络功能开关 */
    bool _multi_net_enabled;
    
public:
    /**
     * @brief 构造函数
     * @details 初始化所有成员变量，设置默认配置
     */
    SimpleCDNET();
    
    /**
     * @brief 初始化CDNET协议栈（单网络模式）
     * @param serial 硬件串口指针（如&Serial1）
     * @param address 本地设备地址（1-254）
     * 
     * @note 默认网络ID为0，MAC地址等于设备地址
     * @warning 地址0为广播地址，255为保留地址
     */
    void begin(HardwareSerial *serial, uint8_t address);
    
    /**
     * @brief 初始化CDNET协议栈（多网络模式）
     * @param serial 硬件串口指针
     * @param net_id 网络标识符（0-255）
     * @param mac_address MAC地址（1-254）
     * 
     * @note 启用多网络功能，支持跨网络通信
     * @warning 确保网络ID和MAC地址在系统中唯一
     */
    void begin(HardwareSerial *serial, uint8_t net_id, uint8_t mac_address);
    
    /**
     * @brief 关闭CDNET协议栈
     * @details 清理资源，关闭串口通信
     */
    void end();
    
    /**
     * @brief Layer 0发送（节点内通信）
     * @param dst 目标地址（1-254）
     * @param port 端口号（0-255）
     * @param data 待发送数据指针
     * @param len 数据长度（最大64字节）
     * 
     * @note 使用Layer 0协议，仅本地网络内通信
     * @warning 数据长度不能超过CDNET_MAX_PACKET_SIZE
     */
    void sendL0(uint8_t dst, uint8_t port, uint8_t *data, uint8_t len);
    
    /**
     * @brief Layer 0接收（节点内通信）
     * @param src 返回源地址指针
     * @param port 返回端口号指针
     * @param buffer 接收数据缓冲区
     * @param max_len 缓冲区最大长度
     * @return 实际接收数据长度，0表示无数据
     * 
     * @note 非阻塞接收，立即返回
     * @warning 确保缓冲区足够大以避免数据截断
     */
    uint8_t readL0(uint8_t *src, uint8_t *port, uint8_t *buffer, uint8_t max_len);
    
    /**
     * @brief Layer 1发送（网络间通信）
     * @param dst 目标地址（1-254）
     * @param port 端口号（0-65535）
     * @param data 待发送数据指针
     * @param len 数据长度（最大64字节）
     * 
     * @note 使用Layer 1协议，支持跨网络通信
     * @warning 需要启用多网络功能
     */
    void sendL1(uint8_t dst, uint16_t port, uint8_t *data, uint8_t len);
    
    /**
     * @brief Layer 1接收（网络间通信）
     * @param src 返回源地址指针
     * @param port 返回端口号指针
     * @param buffer 接收数据缓冲区
     * @param max_len 缓冲区最大长度
     * @return 实际接收数据长度，0表示无数据
     * 
     * @note 支持跨网络数据接收
     * @warning 需要启用多网络功能
     */
    uint8_t readL1(uint8_t *src, uint16_t *port, uint8_t *buffer, uint8_t max_len);
    
    /**
     * @brief 发送数据包（高级接口）
     * @param sock 套接字指针
     * @param pkt 待发送数据包指针
     * 
     * @note 使用CDNET核心协议栈发送
     * @warning 确保套接字已正确绑定
     */
    void sendPacket(cdn_sock_t *sock, cdn_pkt_t *pkt);
    
    /**
     * @brief 接收数据包（高级接口）
     * @param sock 套接字指针
     * @return 接收到的数据包指针，NULL表示无数据
     * 
     * @note 非阻塞接收，需要定期调用
     * @warning 使用后需要释放数据包内存
     */
    cdn_pkt_t* receivePacket(cdn_sock_t *sock);
    
    /**
     * @brief 绑定套接字到指定端口
     * @param sock 套接字指针
     * @param port 端口号（0-65535）
     * @return 0成功，负值表示错误
     * 
     * @note 绑定后套接字可接收该端口数据
     * @warning 端口已被占用时返回错误
     */
    int bindSocket(cdn_sock_t *sock, uint16_t port);
    
    /**
     * @brief 检查是否有数据可接收
     * @return true表示有数据，false表示无数据
     * 
     * @note 快速检查，不处理数据
     * @warning 需要在loop()中定期调用
     */
    bool available();
    
    /**
     * @brief 更新协议栈状态
     * @details 处理接收、发送、路由等任务
     * 
     * @note 必须在loop()中定期调用
     * @warning 不调用会导致数据丢失
     */
    void update();
    
    /**
     * @brief 设置接收过滤器
     * @param filter 过滤器值（0-255）
     * 
     * @note 过滤不需要的地址或广播
     * @warning 过滤器0表示接收所有数据
     */
    void setFilter(uint8_t filter);
    
    /**
     * @brief 设置通信波特率
     * @param baud 波特率值（bps）
     * 
     * @note 标准值：1000000, 500000, 250000
     * @warning 必须与网络中其他设备一致
     */
    void setBaudRate(uint32_t baud);
    
    /**
     * @brief 启用或禁用多播功能
     * @param enable true启用，false禁用
     * 
     * @note 启用后支持组播通信
     * @warning 需要网络硬件支持
     */
    void enableMulticast(bool enable = true);
    
    /**
     * @brief 启用或禁用多网络功能
     * @param enable true启用，false禁用
     * 
     * @note 启用后支持跨网络通信
     * @warning 增加内存使用和处理开销
     */
    void enableMultiNet(bool enable = true);
    
    /**
     * @brief 设置网络标识符
     * @param net_id 网络ID（0-255）
     * 
     * @note 用于多网络环境中的网络区分
     * @warning 必须与网络配置匹配
     */
    void setNetworkId(uint8_t net_id);
    
    /**
     * @brief 设置MAC地址
     * @param mac MAC地址（1-254）
     * 
     * @note 本地设备的唯一标识符
     * @warning 地址冲突会导致通信异常
     */
    void setMacAddress(uint8_t mac);
    
    /**
     * @brief 获取本地设备地址
     * @return 当前设备地址
     * 
     * @note 与MAC地址相同
     */
    uint8_t getAddress() { return _cdbus.getAddress(); }
    
    /**
     * @brief 检查协议栈是否已初始化
     * @return true已初始化，false未初始化
     * 
     * @note 用于状态检查
     */
    bool isInitialized() { return _cdbus.isInitialized(); }
    
    /**
     * @brief 获取CDNET命名空间指针
     * @return CDNET核心命名空间指针
     * 
     * @note 用于高级功能和直接访问
     * @warning 需要了解CDNET核心API
     */
    cdn_ns_t* getNamespace() { return &_cdnet_ns; }
    
private:
    /**
     * @brief 初始化CDNET协议栈
     * @details 配置协议参数，初始化数据结构
     * 
     * @note 在begin()中自动调用
     */
    void initializeCDNET();
    
    /**
     * @brief 初始化CDNET核心功能
     * @details 初始化命名空间、内存池、链表等
     * 
     * @note 在initializeCDNET()中调用
     */
    void initializeCore();
};

#endif // SIMPLE_CDNET_H